home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************
- * PCFILERD.C - program from The C Gazette, Summer 88 issue,
- * Volume 2 No. 1. page 45. The program demonstrates access
- * to PC-FILE records by index and through the data records
- * themselves. (c) 1988 Billy Rubin. Use freely but acknow-
- * ledge author.
- *************************************************************/
-
- /* The following two fields are dependent on the file layout. They
- should ideally be set at compilation time as command line
- switches so as to be tailored to specific layouts. They have
- been commented out by typist as command line switches will
- be used.
- The typist used the Quick C Small memory model to compile
- pcfilerd. My command line is:
-
- qcl /c /Zi /DRECLEN=75 /DFIELDS=4 pcfilerd.c
-
- The /c option is to create an object file.
- The /Zi option is for compiling with Codeview information included.
- The first /D option, /DRECLEN= 75, defines RECLEN from the comm-
- and line. My records for this particular database are 75 columns,
- not including spaces between fields or the carriage return.
- The second /D option, /DFIELDS=4, defines FIELDS from the comm-
- and line. In my database, there are 4 fields per record.
- */
-
- /* #define RECLEN */ /* The length of the record as defined */
- /* #define FIELDS */ /* Number of fields in sample record */
-
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
-
- #ifndef SEEK_SET
- #define SEEK_SET 0
- #endif
-
- FILE *Idx_file; /* The index file */
- FILE *Data_file; /* The corresponding data file */
-
- #define IDX_LEN (FIELDS * 2 + 2)
- #define DATA_LEN (RECLEN + 1)
-
- char Idx_buffer [IDX_LEN];
- char Data_buffer [DATA_LEN];
-
- void read_index() /* Reads the next index record */
- {
- fread (Idx_buffer, IDX_LEN, 1, Idx_file);
- }
-
- unsigned int compute_offset() /* Record offset is in last 2 bytes of Idx */
- { /* Since file begins at record 0, subtract */
- unsigned int u; /* 1 from record count. */
- u = *( (unsigned int *) (Idx_buffer + IDX_LEN - 2));
- return (u-1);
- }
-
- void read_data() /* Reads the next data record */
- { /* First gets record # from index file */
- /* then goes to that location for data */
- unsigned int offset;
- long distance;
- offset = compute_offset(); /* Get offset into data file */
- distance = ( (long) offset * DATA_LEN);
- fseek (Data_file, distance, SEEK_SET);
- fread (Data_buffer, DATA_LEN, 1, Data_file);
- }
-
- int get_record()
- {
-
- for( ;; ) {
- read_index();
- switch (Idx_buffer[0]) { /* Test the first byte */
- case '\\': /* Backslash = EOF */
- return (EOF);
- case '/': /* Forward slash = deleted record */
- continue;
- default: /* Else it's a data record */
- read_data();
- }
- break;
- }
- }
-
- void print_line() /* Just a sample application: print the first */
- { /* forty characters of the data record */
-
- char line [DATA_LEN];
-
- strncpy (line, Data_buffer, DATA_LEN);
- if (strlen (line) > DATA_LEN - 1) /* Remember, strncpy() may not end */
- line[DATA_LEN - 1] = '\0'; /* the string with a null. */
- printf ("%s\n", line);
- }
-
- main(argc, argv)
- int argc;
- char *argv [];
- {
-
- char idx_name [31], data_name [30];
-
- if (argc < 2) {
- puts ("Usage: pcfilerd filename (no extension)");
- exit (5);
- }
- else { /* The file name is common to index and data files */
- strcpy (idx_name, argv[1]);
- strcat (idx_name, ".inx");
- strcpy (data_name, argv[1]);
- strcat (data_name, ".dta");
- }
- if ( (Idx_file = (fopen (idx_name, "rb"))) == NULL) {
- printf ("Error opening: %s\n", idx_name);
- exit (5);
- }
- if ( (Data_file = (fopen (data_name, "rb"))) == NULL) {
- printf ("Error opening: %s\n", data_name);
- exit (6);
- }
- while (get_record() != EOF)
- print_line();
- }
-
-